package com.shutong.edu.invoke.retry.annotation;

import com.shutong.edu.invoke.retry.provider.FallbackProvider;

import java.lang.annotation.*;

/**
 *
 * @ClassName: EnableRetry.java
 * @author: Naughty Guo
 * @date: Jun 2, 2016
 */
@Inherited
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableRetry {

    /**
     * will trigger retry if thrown exception match the value which in exceptions array.<br>
     * default retry any exception.
     */
    Class<? extends Throwable>[] exceptions() default { Throwable.class };

    /**
     * will not trigger retry if thrown exception match the value which in ignoreExceptions array.
     */
    Class<? extends Throwable>[] ignoreExceptions() default {};

    /**
     * retry times. default 3 times.
     */
    short times() default 3;

    /**
     * how long will do retry again. default 3 seconds.
     */
    long interval() default 3000;

    /**
     * if retry not success by max retry times, a fallback will be execute and result will be returned
     * as execute result. if fallback method be invoked error, an exception will be thrown immediately.<br>
     * attention: if fallbackMethod() and fallbackProvider() exist same time, only fallback() will be used.
     */
    String fallbackMethod() default "";

    /**
     * can also define a new class(implements FallbackProvider) for fallback.<br>
     * attention: if fallback() and fallbackProvider() exist same time, only fallback() will be used.
     */
    Class<? extends FallbackProvider> fallbackProvider() default FallbackProvider.class;

    /**
     * define result which is returned by invoking the target method alias. <br>
     * check whether need to retry if the result is match the retry boolean expression(@link exp()).<br>
     */
    String val() default "";

    /**
     * define MVEL expression for invoking boolean expression.<br>
     * eg. if the target method has not any exception and return result, but the result's state is not success,
     * then you may be re-execute the target method for the success state. you can using expression for whether
     * success checking.<br>
     */
    String exp() default "";
}
